<script setup lang="ts">
import { inject, onMounted, onUnmounted, reactive, ref, watch } from 'vue';

import { ElCheck, ElDelete, ElInfoFilled, ElPlus } from '@vben/icons';

// import AddRuleDialog from './AddRuleDialog.vue'
import {
  ElAlert,
  ElButton,
  ElCheckbox,
  ElCol,
  ElCollapse,
  ElCollapseItem,
  ElIcon,
  ElInput,
  ElInputNumber,
  ElMessage,
  ElMessageBox,
  ElOption,
  ElPopover,
  ElRow,
  ElSelect,
  ElTable,
  ElTableColumn,
} from 'element-plus';

import { vectorServiceApi } from '#/api';
import { usePublicStore } from '#/store';
import { getRampUrl } from '#/utils';

interface ColorRampItem {
  id: number;
  label: string;
  value: string;
}

const emits = defineEmits(['confirmBtnAvalible']);
const publicStore = usePublicStore();
const currentLayer = inject('currentSelectedLayer') as any;
const activeNames = ref(['globalRules']);
const fieldList = ref<Array<any>>([]); // 当前图层的字段列表
// const gradualValueRender = new GradualValueRender()
// const basedRule = ref('global')
const globalRules = ref<Array<any>>([]);
const basedZoomRules = ref<Array<any>>([]);
// const isRuleSettingDialogShow = ref(false)
const selectedLayer = inject('currentSelectedLayer') as any;
const emptyText = ref('该数据不含字段');
const keepingLayer = ref(true);

const heatmapOptions = reactive({
  layer: selectedLayer.value,
  colorRamp: 'Yellow-Red-Purple',
  weightField: '',
  // 根据weightField是否为空来判断启用值还是范围
  'heatmap-weight': {
    value: 1,
    range: [0, 1],
  },
  maxFieldVal: 0,
  keepingLayer:
    currentLayer.value.renderType[1] === 'heatMap' ? false : keepingLayer,
  layerOptions: {
    layout: {
      visibility: 'visible',
    },
    // 根据每个参数的mode选择不同的渲染方式;
    // 若mode为global则启用value字段存储单独的值，无视其range值;
    // 若mode为basedZoom则启用range字段存储范围值，无视其value值;
    paint: {
      'heatmap-intensity': {
        mode: 'global',
        value: 1,
        range: [0, 10],
      },
      'heatmap-opacity': {
        mode: 'global',
        value: 1,
        range: [1, 0],
      },
      'heatmap-radius': {
        mode: 'global',
        value: 10,
        range: [5, 50],
      },
      // 'heatmap-weight': {
      //   mode: 'global',
      //   value: 1,
      //   range: [0, 1]
      // }
    },
  },
  // mode为basedZoom的参数所需要的公共字段
  basedZoomOptions: {
    interpolateMethod: 'linear',
    zoomRange: [0, 14],
  },
  mapLayer: {} as any,
});

const colorRampSelect = ref(); // 用于获取下拉框dom
const colorRampList = ref<Array<ColorRampItem>>([
  {
    id: 1,
    label: '经典',
    value: 'Classical',
  },
  {
    id: 2,
    label: '黄-红',
    value: 'Yellow-Red',
  },
  {
    id: 3,
    label: '黄-橙-红',
    value: 'Yellow-Orange-Red',
  },
  {
    id: 4,
    label: '黄-红-紫',
    value: 'Yellow-Red-Purple',
  },
  {
    id: 5,
    label: '黄-绿-蓝',
    value: 'Yellow-Green-Blue',
  },
  {
    id: 6,
    label: '红-黄-绿',
    value: 'Red-Yellow-Green',
  },
]);

// const openRuleSetting = () => {
//   console.log('123');
//   console.log(isRuleSettingDialogShow.value);
//   // console.log(basedRule);

//   isRuleSettingDialogShow.value = true

//   // console.log(isPolygonStyleSettingDialogShow.value)
// }

const handleColorRampSelectChange = (val: any) => {
  let img = null;
  colorRampList.value.forEach((item: any) => {
    if (item.value === val) {
      img = getRampUrl(item.value);
    }
  });
  // console.log(img)
  colorRampSelect.value.$el.children[0].children[0].children[1].setAttribute(
    'style',
    `
        background: url(${img}) no-repeat;
				background-position: 10px center;
				background-size: 80px 20px;
				text-indent: 100px;
				`,
  );
};
// 根据选择的字段获取其最大值
const handleFieldSelectChange = async (val: any) => {
  const uniqueValues = await vectorServiceApi.getUniqueValuesFromGeojson(
    currentLayer.value.source,
    val,
    'DESC',
  );
  if (typeof uniqueValues[0] === 'number' && !Number.isNaN(uniqueValues[0])) {
    heatmapOptions.maxFieldVal = uniqueValues[0];
  } else {
    ElMessage.error('只能选取数值类型的字段，请重新选择!');
    heatmapOptions.weightField = '';
  }
};
const renderParamsReturn = () => {
  const renderParams =
    currentLayer.value.templateParams ?? currentLayer.value.renderParams;
  delete currentLayer.value.templateParams;
  heatmapOptions.colorRamp = renderParams.colorRamp;
  heatmapOptions.weightField = renderParams.weightField;

  heatmapOptions['heatmap-weight'] = renderParams['heatmap-weight'];
  keepingLayer.value = renderParams.keepingLayer;
  heatmapOptions.layerOptions.paint = renderParams.paint;
  heatmapOptions.basedZoomOptions.zoomRange = renderParams.zoomRange;
  // 如果原先有字段值，先获取到字段值的最大值
  if (renderParams.weightField) {
    handleFieldSelectChange(renderParams.weightField);
  } else {
    // 防止原先没使用权重字段的情况下，热力图权重属性只有value项，没有range项
    if (!heatmapOptions['heatmap-weight'].range) {
      heatmapOptions['heatmap-weight'].range = [0, 1];
    }
  }

  // 还原规则（每个参数都有mode项时）
  for (const param in heatmapOptions.layerOptions.paint) {
    const mode = (heatmapOptions.layerOptions.paint as any)[param].mode;
    if (mode === 'global') {
      const value = (heatmapOptions.layerOptions.paint as any)[param].value;
      const restoredRule = {
        param,
        value,
      };
      globalRules.value.push(restoredRule);
    } else if (mode === 'basedZoom') {
      const range = (heatmapOptions.layerOptions.paint as any)[param].range;
      const restoredRule = {
        param,
        range,
      };
      basedZoomRules.value.push(restoredRule);
    }
  }
};
// 请求当前图层字段值
const requestFields = async () => {
  fieldList.value = await vectorServiceApi.getFieldsFromGeojson(
    currentLayer.value.source,
  );
};
const addGlobalRule = () => {
  if (
    globalRules.value.length > 0 &&
    (!globalRules.value[globalRules.value.length - 1].param ||
      !globalRules.value[globalRules.value.length - 1].value)
  ) {
    ElMessage({
      message: '规则不能为空',
      type: 'warning',
    });
    return;
  }
  const isEmptyBasedZoomRules = basedZoomRules.value.some(
    (item) => !item.param || !item.range[0] || !item.range[1],
  );
  if (isEmptyBasedZoomRules) {
    ElMessage({
      message: '规则不能为空',
      type: 'warning',
    });
    return;
  }
  if (globalRules.value.length + basedZoomRules.value.length >= 3) {
    ElMessage({
      message: '超出规则上限',
      type: 'warning',
    });
    return;
  }
  globalRules.value.push({
    param: '', // 根据表头的列名添加对应的属性
    value: '',
  });
};
const addBasedZoomRule = () => {
  if (
    basedZoomRules.value.length > 0 &&
    (!basedZoomRules.value[basedZoomRules.value.length - 1].param ||
      !basedZoomRules.value[basedZoomRules.value.length - 1].range[0] ||
      !basedZoomRules.value[basedZoomRules.value.length - 1].range[1])
  ) {
    ElMessage({
      message: '规则不能为空',
      type: 'warning',
    });
    return;
  }
  const isEmptyGlobalRules = globalRules.value.some(
    (item) => !item.param || !item.value,
  );
  if (isEmptyGlobalRules) {
    ElMessage({
      message: '规则不能为空',
      type: 'warning',
    });
    return;
  }
  if (basedZoomRules.value.length + globalRules.value.length >= 3) {
    ElMessage({
      message: '超出规则上限',
      type: 'warning',
    });
    return;
  }
  basedZoomRules.value.push({
    param: '', // 根据表头的列名添加对应的属性
    range: [] as number[],
  });
};
const deleteGlobalRule = (index: number) => {
  globalRules.value.splice(index, 1);
};
const deleteBasedZoomRule = (index: number) => {
  basedZoomRules.value.splice(index, 1);
};
const handGlobalRuleSelectChange = (val: any, index: number) => {
  // 检查是否存在相同的参数
  let msg = '已存在相同参数的全局规则';
  // let repetitiveBasedZoomRule = false
  const existingGlobalRule = globalRules.value.findIndex(
    (rule) => rule.param === val,
  );
  // console.log('当前全局规则', existingGlobalRule);
  // console.log('当前选择的规则', val);
  // console.log('当前选择的规则的index', index);

  const existingBasedZoomRule = basedZoomRules.value.find(
    (rule) => rule.param === val,
  );
  if (existingBasedZoomRule) {
    msg = '已存在相同参数的基于缩放规则';
  }
  if (
    (existingGlobalRule !== -1 && index !== existingGlobalRule) ||
    existingBasedZoomRule
  ) {
    ElMessageBox.alert(msg, '重复定义规则', {
      confirmButtonText: 'OK',
      callback: () => {
        // 重置下拉选择框的值为空
        globalRules.value[globalRules.value.length - 1].param = '';
      },
    });
  }
};
const handBasedZoomRuleSelectChange = (val: any, index: number) => {
  // 检查是否存在相同的参数
  let msg = '已存在相同参数的基于缩放规则';
  // let repetitiveBasedZoomRule = false
  const existingGlobalRule = globalRules.value.find(
    (rule) => rule.param === val,
  );
  const existingBasedZoomRule = basedZoomRules.value.findIndex(
    (rule) => rule.param === val,
  );
  if (existingGlobalRule) {
    msg = '已存在相同参数的全局规则';
  }
  if (
    (existingBasedZoomRule !== -1 && index !== existingBasedZoomRule) ||
    existingGlobalRule
  ) {
    ElMessageBox.alert(msg, '重复定义规则', {
      confirmButtonText: 'OK',
      callback: () => {
        // 重置下拉选择框的值为空
        basedZoomRules.value[basedZoomRules.value.length - 1].param = '';
      },
    });
  }
};

const confirmRules = () => {
  if (globalRules.value.length + basedZoomRules.value.length < 3) {
    ElMessage({
      message: '规则未添加完全',
      type: 'warning',
    });
    return;
  }

  // 遍历 globalRules 数组并传递值给 heatmapOptions 数据结构
  globalRules.value.forEach((rule) => {
    const param = rule.param;
    const value = Number.parseFloat(rule.value);
    (heatmapOptions.layerOptions.paint as any)[param].value = value;
    (heatmapOptions.layerOptions.paint as any)[param].mode = 'global';
  });
  basedZoomRules.value.forEach((rule) => {
    const param = rule.param;
    const range = rule.range.map((val: any) => Number.parseFloat(val));
    (heatmapOptions.layerOptions.paint as any)[param].range = range;
    (heatmapOptions.layerOptions.paint as any)[param].mode = 'basedZoom';
  });
  emits('confirmBtnAvalible', true);
  ElMessage.success('规则确认成功！');
  // console.log(heatmapOptions);

  // serviceDataVSceneApi.getSceneLayer(selectedLayer.value.id, "geojson", "heatmap").then(res => {
  //   if (res.code === 200) {
  //     console.log(res.data)
  //     heatmapOptions.mapLayer = res.data
  //     // 遍历 globalRules 数组并传递值给 heatmapOptions 数据结构
  //     globalRules.value.forEach(rule => {
  //       const param = rule.param
  //       const value = parseFloat(rule.value);
  //       (heatmapOptions.layerOptions.paint as any)[param].value = value;
  //       (heatmapOptions.layerOptions.paint as any)[param].mode = 'global'
  //     })
  //     basedZoomRules.value.forEach(rule => {
  //       const param = rule.param
  //       const range = rule.range.map((val: any) => parseFloat(val));
  //       (heatmapOptions.layerOptions.paint as any)[param].range = range;
  //       (heatmapOptions.layerOptions.paint as any)[param].mode = 'basedZoom';
  //     })
  //     emits('confirmBtnAvalible', true)
  //     ElMessage.success('规则确认成功！')
  //     // console.log(heatmapOptions);
  //   }
  // })
};
watch(
  heatmapOptions,
  () => {
    publicStore.setRenderOptions(heatmapOptions);
  },
  {
    deep: true,
  },
);
onMounted(async () => {
  // console.log(singleValueRenderParams)
  const { renderType, templateParams } = currentLayer.value;
  //  当原先渲染方式是该方式时，或现在渲染方式是来自于模板时，需要参数恢复（赋值）
  if (renderType[1] === 'heatMap' || templateParams) {
    renderParamsReturn();
  }
  emits('confirmBtnAvalible', false);
  handleColorRampSelectChange(heatmapOptions.colorRamp); // 当前默认的色带
  await requestFields(); // 请求字段
  // 如果是模板，默认第一个字段渲染(为了演示暂定，默认不选择字段)
  if (templateParams) {
    heatmapOptions.weightField = fieldList.value[0];
    handleFieldSelectChange(heatmapOptions.weightField);
  }
});
onUnmounted(() => {
  emits('confirmBtnAvalible', true);
});
</script>

<template>
  <div class="all">
    <ElRow class="itemRow">
      <ElCol :span="4">
        <span class="label-style"> 权重字段： </span>
      </ElCol>
      <ElCol :span="20">
        <ElSelect
          size="small"
          v-model="heatmapOptions.weightField"
          placeholder="选择将与heatmap-weight关联的字段（非必选）"
          style="width: 100%"
          @change="handleFieldSelectChange"
          :no-data-text="emptyText"
        >
          <ElOption
            v-for="item in fieldList"
            :key="item"
            :label="item"
            :value="item"
          />
        </ElSelect>
      </ElCol>
    </ElRow>
    <ElRow class="itemRow" v-if="!heatmapOptions.weightField">
      <ElCol :span="4">
        <span class="label-style"> 权重值： </span>
      </ElCol>
      <ElCol :span="20">
        <ElInput
          v-model.number="heatmapOptions['heatmap-weight'].value"
          placeholder="请输入权重"
          size="small"
        />
      </ElCol>
    </ElRow>
    <ElRow class="itemRow" v-if="heatmapOptions.weightField">
      <ElCol :span="4">
        <span class="label-style"> 权重范围： </span>
      </ElCol>
      <ElCol :span="9">
        <ElInput
          v-model.number="heatmapOptions['heatmap-weight'].range[0]"
          placeholder="Please input"
        />
      </ElCol>
      <ElCol :span="2" style="text-align: center">
        <span>--</span>
      </ElCol>
      <ElCol :span="9">
        <ElInput
          v-model.number="heatmapOptions['heatmap-weight'].range[1]"
          placeholder="Please input"
        />
      </ElCol>
    </ElRow>
    <ElRow class="itemRow">
      <ElCol :span="4">
        <span class="label-style"> 颜色： </span>
      </ElCol>
      <ElCol :span="20">
        <ElSelect
          ref="colorRampSelect"
          @change="handleColorRampSelectChange"
          v-model="heatmapOptions.colorRamp"
          placeholder="请选择输入色带"
          style="width: 100%"
          size="small"
        >
          <ElOption
            v-for="item in colorRampList"
            :key="item.id"
            :label="item.label"
            :value="item.value"
          >
            <ElRow type="flex" :gutter="20" justify="center">
              <ElCol :span="18">
                <img
                  :src="getRampUrl(item.value)"
                  style="float: left; height: 30px"
                />
              </ElCol>
              <ElCol :span="6">
                <span>{{ item.label }}</span>
              </ElCol>
            </ElRow>
          </ElOption>
        </ElSelect>
      </ElCol>
    </ElRow>
    <ElCollapse v-model="activeNames" accordion>
      <ElCollapseItem title="全局规则" name="globalRules">
        <ElRow class="itemRow">
          <ElCol :span="4">
            <ElButton
              type="primary"
              size="small"
              :icon="ElPlus"
              @click="addGlobalRule"
              style="height: 30px; padding: 5px; margin-top: 59px"
            >
              添加规则
            </ElButton>
          </ElCol>
          <ElCol :span="20" style="height: 160px">
            <div
              v-if="globalRules.length === 0"
              style="
                width: 100%;
                height: 150px;
                line-height: 150px;
                color: rgb(127 127 127 / 50%);
                text-align: center;
              "
            >
              No Global Rules
            </div>
            <ElTable
              :data="globalRules"
              style="width: 100%"
              max-height="170"
              v-show="globalRules.length > 0"
              size="small"
            >
              <ElTableColumn label="参数" width="150">
                <template #default="scope">
                  <!-- <el-input v-model="scope.row.param"></el-input> -->
                  <ElSelect
                    size="small"
                    v-model="scope.row.param"
                    placeholder="请选择参数"
                    style="width: 100%"
                    @change="
                      handGlobalRuleSelectChange(scope.row.param, scope.$index)
                    "
                  >
                    <ElOption
                      v-for="item in Object.keys(
                        heatmapOptions.layerOptions.paint,
                      )"
                      :key="item"
                      :label="item"
                      :value="item"
                    />
                  </ElSelect>
                </template>
              </ElTableColumn>
              <ElTableColumn label="值" width="200">
                <template #default="scope">
                  <ElInput v-model="scope.row.value" size="small" />
                </template>
              </ElTableColumn>
              <ElTableColumn>
                <template #default="scope">
                  <ElButton
                    type="danger"
                    size="small"
                    @click.prevent="deleteGlobalRule(scope.$index)"
                    :icon="ElDelete"
                    style="margin-right: 5px"
                  />
                </template>
              </ElTableColumn>
            </ElTable>
          </ElCol>
          <!-- <el-col :span="5">
        <el-button type="info" @click="openRuleSetting" size="small">添加规则</el-button>
      </el-col> -->
        </ElRow>
      </ElCollapseItem>
      <ElCollapseItem title="缩放规则" name="basedZoomRules">
        <ElRow class="itemRow">
          <ElCol :span="4">
            <ElButton
              type="primary"
              size="small"
              :icon="ElPlus"
              @click="addBasedZoomRule"
              style="height: 30px; padding: 5px; margin-top: 59px"
            >
              添加规则
            </ElButton>
          </ElCol>
          <ElCol :span="20" style="height: 160px">
            <div
              v-if="basedZoomRules.length === 0"
              style="
                width: 100%;
                height: 150px;
                line-height: 150px;
                color: rgb(127 127 127 / 50%);
                text-align: center;
              "
            >
              No Zoom-based Rules
            </div>
            <ElTable
              :data="basedZoomRules"
              style="width: 100%"
              max-height="170"
              v-show="basedZoomRules.length > 0"
              size="small"
            >
              <ElTableColumn label="参数" width="150">
                <template #default="scope">
                  <!-- <el-input v-model="scope.row.param"></el-input> -->
                  <ElSelect
                    size="small"
                    v-model="scope.row.param"
                    placeholder="请选择参数"
                    style="width: 100%"
                    @change="
                      handBasedZoomRuleSelectChange(
                        scope.row.param,
                        scope.$index,
                      )
                    "
                  >
                    <ElOption
                      v-for="item in Object.keys(
                        heatmapOptions.layerOptions.paint,
                      )"
                      :key="item"
                      :label="item"
                      :value="item"
                    />
                  </ElSelect>
                </template>
              </ElTableColumn>
              <ElTableColumn label="起始值" width="100">
                <template #default="scope">
                  <ElInput v-model="scope.row.range[0]" size="small" />
                </template>
              </ElTableColumn>
              <ElTableColumn label="终止值" width="100">
                <template #default="scope">
                  <ElInput v-model="scope.row.range[1]" size="small" />
                </template>
              </ElTableColumn>
              <ElTableColumn>
                <template #default="scope">
                  <ElButton
                    type="danger"
                    size="small"
                    @click.prevent="deleteBasedZoomRule(scope.$index)"
                    :icon="ElDelete"
                    style="margin-right: 5px"
                  />
                </template>
              </ElTableColumn>
            </ElTable>
          </ElCol>
          <!-- <el-col :span="5">
        <el-button type="info" @click="openRuleSetting" size="small">添加规则</el-button>
      </el-col> -->
        </ElRow>
        <ElRow class="itemRow">
          <ElCol :span="5">
            <span class="label-style"> 缩放范围： </span>
          </ElCol>
          <ElCol :span="9">
            <span>From：</span>
            <ElInputNumber
              v-model="heatmapOptions.basedZoomOptions.zoomRange[0]"
              :disabled="basedZoomRules.length === 0"
              :min="0"
              :max="20"
              style="margin-top: 2px"
              size="small"
            />
          </ElCol>
          <ElCol :span="9" :offset="1">
            <span>To：</span>
            <ElInputNumber
              v-model="heatmapOptions.basedZoomOptions.zoomRange[1]"
              :disabled="basedZoomRules.length === 0"
              :min="0"
              :max="20"
              style="margin-top: 2px"
              size="small"
            />
          </ElCol>
        </ElRow>
      </ElCollapseItem>
    </ElCollapse>
    <div class="keep-layer" v-if="currentLayer.renderType[1] !== 'heatMap'">
      <ElCheckbox
        v-model="keepingLayer"
        label="保留原图层"
        size="large"
      />&nbsp;
      <ElPopover :width="170" placement="bottom">
        <template #reference>
          <ElIcon size="14" style="cursor: pointer">
            <ElInfoFilled />
          </ElIcon>
        </template>
        <template #default>
          <div style="display: flex; flex-direction: column; gap: 16px">
            <div>
              <p style="margin: 0; font-size: 13px">取消该选项将覆盖原图层</p>
            </div>
          </div>
        </template>
      </ElPopover>
      &nbsp;<ElAlert
        title="将生成新的图层，新图层将不再支持热力图渲染以外的渲染方式"
        :closable="false"
        type="info"
        center
        style="height: 30px"
      />
    </div>
    <div
      style="
        display: flex;
        align-items: center;
        justify-content: center;
        height: 50px;
      "
    >
      <ElButton
        type="primary"
        size="small"
        :icon="ElCheck"
        @click="confirmRules"
        style="height: 30px"
      >
        确认规则
      </ElButton>
    </div>
  </div>
  <!-- <AddRuleDialog :is-rule-setting-dialog-show="isRuleSettingDialogShow" :mode="basedRule"
    @close-rule-setting-dialog="isRuleSettingDialogShow = false" /> -->
</template>

<style scoped>
.all {
  width: 100%;
}

.itemRow {
  width: 100%;
  padding: 5px;
}

.el-input {
  width: 100%;
}

.label-style {
  font-size: 15px;
}

.colorInput {
  caret-color: transparent;
}

:deep(.colorInput .el-input__inner:hover) {
  cursor: pointer;
}

:deep(.el-table .el-table__cell) {
  text-align: center;
}

.legend {
  margin-top: 2px;
}

:deep(.el-table:not(.el-table--border) .el-table__cell) {
  border: none;

  /* 去除表格边框 */
}

:deep(.el-table--small .cell) {
  height: 25px;
}

:deep(.el-collapse-item__header) {
  font-size: 15px;
  font-weight: 600;
}

.keep-layer {
  display: flex;
  align-items: center;
  justify-content: left;
}

:deep(.el-alert) {
  --el-alert-padding: 8px 0px;

  padding: var(--el-alert-padding);
}

:deep(.el-alert__title) {
  font-size: 13px;
}
</style>
